local httparg    = require("shared.api.httparg")
local response   = require("shared.api.response")
local def        = require("shared.api.def")
local config     = require("config")
local tag        = httparg.tag()
local assertion  = httparg.assertion
local util                  = require "proxy.game.common.util"
local fill_response_header  = util.fill_response_header
local is_match_content_type = util.is_match_content_type
local get_content_decoder   = util.get_content_decoder
local ngx        = _G.ngx
local ERROR_CODE = def.ERROR_CODE
local AMOUNT_SCALE = 10

local cjson = require "cjson.safe"
      cjson.encode_max_depth(32)
      cjson.decode_max_depth(32)

local bigdecimal = require("bigdecimal")
      bigdecimal.digit_separation_count(0)
      bigdecimal.digit_leader('\0')


local ARGS = {
  -- exist body?
  tag.body('json', 'required'),

  username         = tag.json.username        ('string', 'required', assertion.non_empty_string()),
  coin_token       = tag.json.coin_token      ('string', 'required', assertion.non_empty_string()),
  coin_amount      = tag.json.coin_amount     ('string', 'required', assertion.non_empty_string()),
  payment_channel  = tag.json.payment_channel ('string',             assertion.non_empty_string()),
  currency         = nil,
  alliance         = nil,
}

-- use coin_toke to get currency
do
    ARGS.coin_token = string.upper(ARGS.coin_token)

    local currency = config.VAR.COIN_TOKEN_MAP[ARGS.coin_token]
    if not currency then
        response.error(ERROR_CODE.UNKNOWN_COIN_TOKEN)
    end
    ARGS.currency = currency
end
-- set alliance
do
    ARGS.alliance = "muse"
end


local dataapi = require("shared.api.dataapi")

-- get player payment channel record
local PAYMENT_CHANNEL
do
  -- default value when ARGS.payment_channel is not empty.
  if ARGS.payment_channel then
    -- export
    PAYMENT_CHANNEL = ARGS.payment_channel
  else
    local reply, err = dataapi.account.view_wallet_address(
      {
        username   = ARGS.username,
        alliance   = ARGS.alliance,
        coin_token = ARGS.coin_token,
        currency   = ARGS.currency,
      })

    if err then
      if err.message ~= def.ERROR_CODE.NO_CONTENT then
        response.error(err)
      end
    else
      -- export
      PAYMENT_CHANNEL = reply.assigned_market
    end
  end
end

-- when PAYMENT_CHANNEL is empty
if (not PAYMENT_CHANNEL) or PAYMENT_CHANNEL == "" then
  PAYMENT_CHANNEL = "cobo"
end


--=========muse=====================================================================================
do
  if PAYMENT_CHANNEL == "muse" then
    local headers             = ngx.req.get_headers()
    local paymentgatewayapi   = require("shared.api.paymentgatewayapi")
    local reply, err          = paymentgatewayapi.withdrawal_fee(
                                headers,
                                PAYMENT_CHANNEL,
                                {
                                  coin_token       = ARGS.coin_token,
                                  amount           = ARGS.coin_amount
                                })
    if err then
      response.error(err)
    end

    local AMOUNT        = bigdecimal.new(ARGS.coin_amount)
    local COIN          = reply.fee_coin
    local fee_amount    = reply.fee_amount
    if bigdecimal.cmp(AMOUNT, fee_amount) < 0 then
      response.error('INSUFFICIENT_BALANCE')
    end
    local actual_amount = AMOUNT - fee_amount
    local FEE_AMOUNT    = bigdecimal.round(fee_amount   , AMOUNT_SCALE):tostring('F')
    local ACTUAL_AMOUNT = bigdecimal.round(actual_amount, AMOUNT_SCALE):tostring('F')

    response.success({
      fee_coin        = COIN,
      fee_amount      = FEE_AMOUNT,
      payout          = ARGS.coin_amount,
      actual_amount   = ACTUAL_AMOUNT,
      payment_channel = PAYMENT_CHANNEL,
    })
    return
  end
end


--=========cobo=====================================================================================
do
  local COIN_TOKEN = string.upper(ARGS.coin_token)
  local COIN       = config.VAR.COIN_TOKEN_MAP[COIN_TOKEN]
  local AMOUNT     = bigdecimal.new(ARGS.coin_amount)

  local FEE_AMOUNT, ACTUAL_AMOUNT

  if not COIN then
    response.error(ERROR_CODE.UNKNOWN_COIN_TOKEN)
  end

  -- valid min withdraw amount
  do
    local min_amount = config.VAR.MIN_WITHDRAW_AMOUNT[COIN]  or  0
    if bigdecimal.cmp(AMOUNT, min_amount) < 0 then
      response.error(ERROR_CODE.AMOUNT_TOO_SMALL)
    end
  end

  do
    local fee_ratio     = config.VAR.WITHDRAW_FEE_RATIO
    local fee_amount    = AMOUNT * fee_ratio
    if bigdecimal.cmp(AMOUNT, fee_amount) < 0 then
      response.error('INSUFFICIENT_BALANCE')
    end
    local actual_amount = AMOUNT - fee_amount

    -- export
    FEE_AMOUNT    = bigdecimal.round(fee_amount   , AMOUNT_SCALE):tostring('F')
    ACTUAL_AMOUNT = bigdecimal.round(actual_amount, AMOUNT_SCALE):tostring('F')
  end

  response.success({
    fee_coin        = COIN,
    fee_amount      = FEE_AMOUNT,
    payout          = ARGS.coin_amount,
    actual_amount   = ACTUAL_AMOUNT,
    payment_channel = PAYMENT_CHANNEL,
  })
end